﻿
#if 1
#define SERVER_NAME cgiServerName
#endif
#if 0
#define SERVER_NAME "www.boutell.com"
#endif
#ifdef WIN32
#define SAVED_ENVIRONMENT "c:\\cgicsave.env"
#else
#define SAVED_ENVIRONMENT "/tmp/cgicsave.env"
#endif /* WIN32 */

#include <stdio.h>
#include "lodepng.h"
#include "cgic.h"
#include "serial.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "minilzo.h"
#include "common.h"
#include <sys/stat.h>
int base64_decode();
void File();
void HandleSubmit();
void CookieSet();
void Color();
void Cookies();
void LoadEnvironment();
void SaveEnvironment();
void FreeBmpData();
void decodeOneStep();
int          targetFile;
mode_t       mode;
char wrkmem[1024*64];
extern char *cgiQueryString;
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
typedef  struct  tagBITMAPFILEHEADER
{ 
 unsigned short int  bfType;       //位图文件的类型，必须为BM 
 unsigned short int  bfSize;       //文件大小，以字节为单位
 unsigned long  bfReserved1; //位图文件保留字，必须为0 
 unsigned short int  bfReserved2; //位图文件保留字，必须为0 
 unsigned long       bfOffBits;  //位图文件头到数据的偏移量，以字节为单位
}BITMAPFILEHEADER; 
typedef  struct  tagBITMAPINFOHEADER 
{ 
	long biSize;                        //该结构大小，字节为单位
	long  biWidth;                     //图形宽度以象素为单位
	long  biHeight;                     //图形高度以象素为单位
	short int  biPlanes;               //目标设备的级别，必须为1 
	short int  biBitCount;             //颜色深度，每个象素所需要的位数
	short int  biCompression;        //位图的压缩类型
	long  biSizeImage;              //位图的大小，以字节为单位
	long  biXPelsPerMeter;       //位图水平分辨率，每米像素数
	long  biYPelsPerMeter;       //位图垂直分辨率，每米像素数
	long  biClrUsed;            //位图实际使用的颜色表中的颜色数
	long  biClrImportant;       //位图显示过程中重要的颜色数
}BITMAPINFOHEADER;

typedef  struct 
{ 
	BITMAPFILEHEADER  bfHeader; //文件信息区
	BITMAPINFOHEADER  biInfo; //图象信息区
}BITMAPFILE;
int GenBmpFile(unsigned char *pData, unsigned int bitCountPerPix, unsigned int width, unsigned int height, const char *filename,const char* imagNB)  
{  
    int r;
    int out_len;
    char img_buffer[10000];
	  char out_data[3072*3];
	  memset(img_buffer, 0,sizeof(img_buffer));
		char tempbuffer[96*96];
    char img_data[32*96];
    char tmp[3];
    int i,count,row,index;
    int w,h,k=0; //bitCountPerPix >> 3;  
    int mcolor;  //24bit
    FILE *fp = fopen(filename, "wb");  
    if(!fp)  
    {  
        printf("fopen failed : %s, %d\n", __FILE__, __LINE__);  
        return 0;  
    }  
  	char header[]={0x42,0x4d,0x36,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,0x00,
  								 0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
  								 0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  								 0x00,0x00,0x00};
    unsigned int bmppitch = ((width*bitCountPerPix + 31) >> 5) << 2;  
    unsigned int filesize = bmppitch*height;  
   // memset(tempbuffer, 0, 9216);
    BITMAPFILE bmpfile;  
  
    bmpfile.bfHeader.bfType = 0x4D42;  
    bmpfile.bfHeader.bfSize =0x2436;// filesize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
    bmpfile.bfHeader.bfReserved1 = 0;  
    bmpfile.bfHeader.bfReserved2 = 0;  
    bmpfile.bfHeader.bfOffBits =sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  
    bmpfile.biInfo.biSize = sizeof(BITMAPINFOHEADER);  
    bmpfile.biInfo.biWidth =96; //width;  
    bmpfile.biInfo.biHeight =32; //height;  
    bmpfile.biInfo.biPlanes = 1;  
    bmpfile.biInfo.biBitCount = bitCountPerPix;  
    bmpfile.biInfo.biCompression = 0;  
    bmpfile.biInfo.biSizeImage = 0;  
    bmpfile.biInfo.biXPelsPerMeter = 0;  
    bmpfile.biInfo.biYPelsPerMeter = 0;  
    bmpfile.biInfo.biClrUsed = 0;  
    bmpfile.biInfo.biClrImportant = 0;  
  //	for(i=0;i<32*96;i+=1)
	//  {
	//		fprintf(cgiOut, "h%x ",pData[i]);
	//  }
    fwrite(header, sizeof(header), 1, fp);
    fseek(fp,54,SEEK_SET);
    bmppitch=3;
    for(k=0,h = 31; h >= 0; h--)    
    {  
       for(w = 0; w < 96; w++,k+=3)
       {  
        //copy by a pixel  
        tempbuffer[k+0] = pData[h* 288 + w*3 + 2];  
				tempbuffer[k+1] = pData[h* 288 + w*3 + 1];  
        tempbuffer[k+2] = pData[h* 288 + w*3 + 0];
  
       } 
     }
    for (index=0,count= 0; count < 96; count++) {
                    for (row = 31; row >=0; row--){
                        if (tempbuffer[96 * row*3 + count * 3 + 2] > 128)  //量化R分量
                        {
                            mcolor = mcolor | 0xE0;
                        }else {
                            mcolor = mcolor | 0x00;
                        }if (tempbuffer[96 * row*3 + count * 3 + 1] > 128)  //量化G分量
                        {
                            mcolor = mcolor | 0x1C;
                        }else{
                            mcolor = mcolor | 0x00;
                        }if (tempbuffer[96 * row*3 + count * 3] > 128)      //量化B分量
                        {
                            mcolor = mcolor | 3;
                        }else{
                            mcolor = mcolor | 0x00;
                        }
                        img_data[index++] =mcolor;
                        mcolor = 0x00;
                    }
     }
    fwrite(tempbuffer, 9216, 1, fp); 
  //  for(i=0;i<96*96;i+=1)
//	  {
//			fprintf(cgiOut, "D%x ",tempbuffer[i]);
	//  }
 //   fprintf(cgiOut, "save bmp\n");
  //  free(tempbuffer);  
  fclose(fp);
  if(OpenComPort(1,19200, 8, "1", 'N') < 0 )
	{
			fprintf(cgiOut, "Error: Opening Com Port %d\n", 1);
			return 0;
	}
	r =lzo1x_1_compress(img_data,sizeof(img_data),out_data,&out_len,wrkmem);//yashuo
  memset(img_data, 0,sizeof(img_data));
  memset(img_buffer, 0,sizeof(img_buffer));
	img_buffer[0]=0;
	img_buffer[1]=atoi(imagNB);
	img_buffer[2]=0;
	img_buffer[3]=0x60;
	img_buffer[4]=0;
	img_buffer[5]=0x20;
  for(index=6,i=0;i<out_len;i++)
	{
		 img_buffer[index++]=out_data[i];
		// fprintf(cgiOut ,"H%d ", out_data[i]);
	}
  if (r == LZO_E_OK){
  	
  	packData_31(0x103,img_buffer, out_len+6);
  	usleep(50);
		CloseComPort();
		usleep(50);
  }else
  	{
  		printf("lzo compress failed !!!\n");
  	}
    return 1;  
}

int cgiMain()
{ 
	if (lzo_init() != LZO_E_OK)
 	{
    printf("internal error - lzo_init() failed !!!\n");
    return 3;
 	}
	cgiHeaderContentType("text/html");
	/* Top of the page */
	fprintf(cgiOut, "<HTML><HEAD>\n");
	fprintf(cgiOut, "<TITLE>uplaod file</TITLE></HEAD>\n");
	fprintf(cgiOut, "<BODY><H1></H1>\n");
	File();
	fprintf(cgiOut, "</BODY></HTML>\n");
	return 0;
}

char* join3(char *s1, char *s2)  
{  
    char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator  
    //in real code you would check for errors in malloc here  
    if (result == NULL) exit (1);  
  
    strcpy(result, s1);  
    strcat(result, s2);  
  
    return result;  
}  
void Cookies()
{
	char **array, **arrayStep;
	char cname[1024], cvalue[1024];
	fprintf(cgiOut, "Cookies Submitted On This Call, With Values (Many Browsers NEVER Submit Cookies):<p>\n");
	if (cgiCookies(&array) != cgiFormSuccess) {
		return;
	}
	arrayStep = array;
	fprintf(cgiOut, "<table border=1>\n");
	fprintf(cgiOut, "<tr><th>Cookie<th>Value</tr>\n");
	while (*arrayStep) {
		char value[1024];
		fprintf(cgiOut, "<tr>");
		fprintf(cgiOut, "<td>");
		cgiHtmlEscape(*arrayStep);
		fprintf(cgiOut, "<td>");
		cgiCookieString(*arrayStep, value, sizeof(value));
		cgiHtmlEscape(value);
		fprintf(cgiOut, "\n");
		arrayStep++;
	}
	fprintf(cgiOut, "</table>\n");
	cgiFormString("cname", cname, sizeof(cname));	
	cgiFormString("cvalue", cvalue, sizeof(cvalue));	
	if (strlen(cname)) {
		fprintf(cgiOut, "New Cookie Set On This Call:<p>\n");
		fprintf(cgiOut, "Name: ");	
		cgiHtmlEscape(cname);
		fprintf(cgiOut, "Value: ");	
		cgiHtmlEscape(cvalue);
		fprintf(cgiOut, "<p>\n");
		fprintf(cgiOut, "If your browser accepts cookies (many do not), this new cookie should appear in the above list the next time the form is submitted.<p>\n"); 
	}
	cgiStringArrayFree(array);
}

int base64_decode( const char * base64, unsigned char * bindata )
{
    int i, j,st;
    unsigned char k;
    unsigned char temp[4];
    for(st=0;base64[st]!=',';st++)
    {
        if(st>200)
        	break;
    }
    fprintf(cgiOut, ":%x ",base64[st++]);
    for ( i = st, j = 0; base64[i] != '\0' ; i += 4 )
    {
        //fprintf(cgiOut, " %x ",base64[i]);
        memset( temp, 0xFF, sizeof(temp) );
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i] )
                temp[0]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i+1] )
                temp[1]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i+2] )
                temp[2]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base64char[k] == base64[i+3] )
                temp[3]= k;
        }

        bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
                ((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
        if ( base64[i+2] == '=' )
            break;

        bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
                ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
        if ( base64[i+3] == '=' )
            break;

        bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
                ((unsigned char)(temp[3]&0x3F));
    }
    return j;
}
	
void File()
{
	char imgNB[10];
	//unsigned char* image;
	char contentType[1000000];
	char buffer[1000000];
//	char buffer1[32*96*4];
	int size;
	//int got;
	if (cgiFormString("value1", buffer, sizeof(buffer)) != cgiFormSuccess) {
		printf("<p>No file was uploaded.<p>\n");
		return;
	}
	if (cgiFormString("value2", imgNB, sizeof(imgNB)) != cgiFormSuccess) {
		printf("<p>Image NB is empty.<p>\n");
		return;
	}
	printf("<p>Image NB is %s \n",imgNB);
	size=base64_decode(buffer,contentType);
	mode=0666;
	targetFile = open(join3("/opt/boa/www/test/image/","temp.png"), O_RDWR|O_CREAT|O_TRUNC|O_APPEND , mode);
  if( targetFile < 0)
  {
    fprintf(cgiOut ,"could not create the file, %s. \n", "temp.png");
    return;
  }
	write(targetFile , contentType , size);
	close(targetFile);
	decodeOneStep("/opt/boa/www/test/image/temp.png",imgNB);
}
void decodeOneStep(const char* filename,const char* imgNB1)
{
  unsigned error;
  unsigned char* image;
  unsigned width, height;
  int i=0;
  error = lodepng_decode24_file(&image, &width, &height, filename);
  if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
 	fprintf(cgiOut, "x%d %d ",width,height);
	GenBmpFile(image,24,96,32,join3(join3("/opt/boa/www/test/image/",imgNB1),".bmp"),imgNB1);
  free(image);
}

void CookieSet()
{
	char cname[1024];
	char cvalue[1024];
	/* Must set cookies BEFORE calling cgiHeaderContentType */
	cgiFormString("cname", cname, sizeof(cname));	
	cgiFormString("cvalue", cvalue, sizeof(cvalue));	
	if (strlen(cname)) {
		
		cgiHeaderCookieSetString(cname, cvalue,
		86400, cgiScriptName, SERVER_NAME);
	}
}

void FreeBmpData(int * pdata)  
{  
    if(pdata)  
    {  
        free(pdata);  
        pdata = NULL;  
    }  
}  

